﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ElectronicCommerce.Framework.Data.Utility.LinqQeuryConditionBuilder
{
    /// <summary>
    /// Database Types supported.
    /// </summary>
    public enum DatabaseType
    {
        SqlServer
    }

    /// <summary>
    /// A DAAB style database object.
    /// </summary>
    public sealed class Database
    {
        #region Static Members

        /// <summary>
        /// Get the default database, a default database is mapping the last connection string in config file, and can be modified manually.
        /// </summary>
        public static Database Default;
        private readonly ISqlQueryFactory queryFactory;
        /// <summary>
        /// Initializes the <see cref="T:Database"/> class.
        /// </summary>
        static Database()
        {
        }

        #endregion



        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="Database"/> class.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="connectionString">The connection string.</param>
        public Database(DatabaseType type)
        {
            switch (type)
            {
                case DatabaseType.SqlServer:
                    this.queryFactory = new SqlServer9QueryFactory();
                    break;
                default:
                    throw new NotSupportedException("Unknow DatabaseType.");
            }
        }

        #endregion

        #region Properties

        /// <summary>
        /// Get the QueryFactory, which can be used to construct complex CRUD command.
        /// </summary>
        public ISqlQueryFactory QueryFactory
        {
            get { return this.queryFactory; }
        }

        #endregion

        #region Public Methods



        #region Extended Query Methods

        /// <summary>
        /// Query from specified custom sql.
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public CustomSqlSection CustomSql(string sql)
        {
            Check.Require(!string.IsNullOrEmpty(sql), "sql could not be null or empty!");

            return new CustomSqlSection(this, sql);
        }

        /// <summary>
        /// Query from specified stored procedure.
        /// </summary>
        /// <param name="spName"></param>
        /// <returns></returns>
        public StoredProcedureSection StoredProcedure(string spName)
        {
            Check.Require(!string.IsNullOrEmpty(spName), "spName could not be null or empty!");

            return new StoredProcedureSection(this, spName);
        }

        /// <summary>
        /// Insert to specified table.
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public InsertSqlSection Insert(IQueryTable table)
        {
            Check.Require(table != null, "table could not be null.");

            return new InsertSqlSection(this, table);
        }

        /// <summary>
        /// Update specified table.
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public UpdateSqlSection Update(IQueryTable table)
        {
            Check.Require(table != null, "table could not be null.");

            return new UpdateSqlSection(this, table);
        }

        /// <summary>
        /// Delete from specified table.
        /// </summary>
        /// <param name="table"></param>
        /// <returns></returns>
        public DeleteSqlSection Delete(IQueryTable table)
        {
            Check.Require(table != null, "table could not be null.");

            return new DeleteSqlSection(this, table);
        }

        /// <summary>
        /// Select from specified table. Supports select with order by, where, group by, inner join, top, skip.
        /// </summary>
        /// <param name="table"></param>
        /// <param name="columns"></param>
        /// <returns></returns>
        public SelectSqlSection Select(IQueryTable table, params ExpressionClip[] columns)
        {
            Check.Require(table != null, "table could not be null.");

            return new SelectSqlSection(this, table, columns);
        }

        #endregion

        #endregion
    }
}
